package sk.stuba.fiit.clientApp.controller;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.security.cert.Certificate;
import java.util.List;

import javax.swing.JOptionPane;

import org.bouncycastle.asn1.ASN1ObjectIdentifier;
import org.bouncycastle.tsp.TimeStampResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;

import sk.stuba.fiit.clientApp.cvo.ArchiveCVO;
import sk.stuba.fiit.clientApp.cvo.ArchiveResultCVO;
import sk.stuba.fiit.clientApp.cvo.BasicPanelDataCVO;
import sk.stuba.fiit.clientApp.cvo.CertificateCVO;
import sk.stuba.fiit.clientApp.cvo.CrlCVO;
import sk.stuba.fiit.clientApp.cvo.UserDetailCVO;
import sk.stuba.fiit.clientApp.cvo.VerifyPanelDataCVO;
import sk.stuba.fiit.clientApp.service.CryptographyService;
import sk.stuba.fiit.clientApp.service.SignatureService;
import sk.stuba.fiit.ltasys.ws.schema.beans.SignatureRequest;
import sk.stuba.fiit.ltasys.ws.schema.beans.Xadestype;

@Controller
public class SignatureController implements
		sk.stuba.fiit.clientApp.controller.Controller {

	@Autowired
	private SignatureService signatureService;
	
	@Autowired
	private CryptographyService cryptographyService;

	/**
	 * ziska samostatnu casovu peciatku nad datami
	 * @param file
	 * @param algorithmId
	 * @param algorithm
	 * @return
	 * @throws IOException
	 */
	public TimeStampResponse getTimeStamp(File file, ASN1ObjectIdentifier algorithmId,
			String algorithm) throws IOException {
		FileInputStream fis = new FileInputStream(file);
		byte[] data = new byte[(int) file.length()];
		fis.read(data);
		fis.close();
		
		try{
			data = cryptographyService.calculateHash(data, algorithm);
		}catch(Exception e){
			e.printStackTrace();
		}

		TimeStampResponse timestamp = null;
		try {
			timestamp = signatureService.getTimeStampToken(data, algorithmId, algorithm);
		} catch (Exception e) {
			e.printStackTrace();
			JOptionPane.showMessageDialog(null,
					"Error ocured durring comunication with timeStamp!",
					"Error", JOptionPane.ERROR_MESSAGE);
		}

		return timestamp;
	}

	public CrlCVO getCRL() throws Exception {
		CrlCVO crl = signatureService.GetAndSaveActualCRL();
		return crl;
	}

	public void getOCSP(Certificate certificate) {

	}
	
	//vytvori podpis s casovimi peciatkami
	public Xadestype createXMLSignature(BasicPanelDataCVO dataCVO) throws Exception {
		SignatureRequest signatureReq = null;
			signatureReq = signatureService.generateSignature(dataCVO);
		return (signatureReq!= null)?signatureReq.getXades().get(0):null;
	}
	
	public List<File> getFilesFromSignature(VerifyPanelDataCVO data){
		List<File> result = null;
		try{
			if(!data.isArchival()){
				result = signatureService.findFileBySignature(data.getPath());
			}else{
				//TODO pripravene pre archivacny balicek
			}
		}catch (Exception e){
			e.printStackTrace();
		}
		return result;
	}

	public boolean verifySignature(VerifyPanelDataCVO data) throws Exception {
		return signatureService.verifySignatureComplex(data);
	}

	public UserDetailCVO setUserAccount(UserDetailCVO userCVO) throws Exception {
		UserDetailCVO result = signatureService.setUserAccount(userCVO.getUsername(),userCVO.getUserPassword(),userCVO.getUserId());
		return result;
	}

	public CertificateCVO getCertificate(String serialNum) throws Exception{
		CertificateCVO result = signatureService.getCertificateBySerialNum(serialNum);
		return result;
	}

	public ArchiveResultCVO archivePackage(ArchiveCVO archiveCvo) throws Exception {
		return signatureService.archive(archiveCvo);
		
	}

	public ArchiveResultCVO deleteArchivePackage(ArchiveCVO archiveCvo) throws Exception {
		return signatureService.deleteArchivePackage(archiveCvo);
	}

	public ArchiveResultCVO obtainArchivePackage(ArchiveCVO archiveCvo) throws Exception{
		return signatureService.obtainArchivePackage(archiveCvo);
	}

}
